﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Wicture.DbRESTFul;
using Wicture.DbRESTFul.Auth;
using Wicture.DbRESTFul.SQL;
using Wicture.QPZS.EPC.API.Domain;

namespace Wicture.QPZS.EPC.API
{
    public class DefaultRepository : DbRESTFulRepository, IAuthProvider
    {
        public Lazy<Dictionary<string, ApiDefinition>> ApiDefinitions { get; private set; }

        public DefaultRepository()
        {
            ApiDefinitions = new Lazy<Dictionary<string, ApiDefinition>>(ListApiDefinitions);
        }

        public void Authenticate(IdentityInfo identityInfo, ConfiguredAPI api)
        {
            // Ignored.
        }

        public Task<IdentityInfo> Login(string username, string password, JToken tags)
        {
            var encript = MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
            var appSecret = Convert.ToBase64String(encript);

            var account = base.Invoke("Login", new { appKey = username, appSecret });
            if (account == null) return Task.FromResult<IdentityInfo>(null);

            if (account.disabled != 0)
            {
                throw new LogicalException("账号被禁用", "401");
            }

            return Task.FromResult(new IdentityInfo
            {
                Id = account.id.ToString(),
                Name = account.name
            });
        }

        public List<ServicePackageApi> GetServicePackageApis(string accountId)
        {
            return Invoke<ServicePackageApi>("GetServicePackageApis", new { accountId });
        }

        public ServicePackage GetServicePackageForAccount(object accountId)
        {
            return Invoke<ServicePackage>("GetServicePackageForAccount", new { accountId });
        }

        private Dictionary<string, ApiDefinition> ListApiDefinitions()
        {
            IEnumerable<ApiDefinition> items = Invoke<ApiDefinition>("ListApiDefinition", null);
            return items.ToDictionary(d => d.Name);
        }

        public void LogInvocation(string apiName, object accountId, decimal cost, string request)
        {
            Invoke("LogApiInvocation", new { apiName, accountId, cost, request });
        }
    }
}
